﻿using System;
using System.Diagnostics;
using DotNetRepository.Cache;
using DotNetRepository.Tools;

namespace DotNetRepository.LinqToSql
{
    /// <summary>
    /// This expiration policy applies only to CacheItems containing a WeakReference. It expires the item when the WeakReference no 
    /// longer references a live object (WeakReference.IsAlive == false).  It also automatically returns the object to the regular
    /// cache if it is touched by the user.
    /// </summary>
    internal class EntityWeakReferenceCacheItemExpiration<TEntity> : ICacheItemExpiration<Guid,WeakReference<EntityCacheItem<TEntity>>>
        where TEntity : class, IEntity
    {
        private WeakReference<EntityCacheItem<TEntity>> _itemReference;
        private Guid _key;

        public bool HasExpired()
        {
            var hasExpired = false;
            if (_itemReference != null)
            {
                if (!_itemReference.IsAlive)
                {
                    hasExpired = true;

                    if (Settings.Default.EnableCacheTrace)
                        Debug.WriteLine(
                            String.Format("Entity with ID {0} has expired from the weak cache.",_key));
                } 
            }

            return hasExpired;
        }

        public void Initialize(CacheItem<Guid, WeakReference<EntityCacheItem<TEntity>>> owningCacheItem)
        {
            _itemReference = owningCacheItem.Value;
            _key = _itemReference.Target.Entity.ID;
        }

        public void ItemTouched() {}

    }
}